<?php

/**
 * 永辉日本药易购edmonedmon SDK
 * @author chenyun
 */

namespace App\Service\VendorClient\Shopedmon;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;
use Hyperf\Utils\WaitGroup;

class ShopedmonApiClient
{
    private $account  = 'Shopedmon';
    protected $config;
    protected $RouteMap = [
        'createOrder'   => 'https://wms.jancohealth.com/WHS/api/system/itapi_edi2?edi_code=PDO_IMPORT',
        'orderCancel'   => 'https://wms.jancohealth.com/WHS/api/system/itapi_edi2?edi_code=PDO_IMPORT',
        'queryGoodsDetail'  => 'https://wms.jancohealth.com/WHS/api/system/itapi_edi2?edi_code=ITEM_BALANCE_ENQUIRY'
    ];
    
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct( $apiBody = [] ) 
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     */
    public function createOrder( $params = [] ) 
    {   
        ini_set('serialize_precision', 16);
        
        if( empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];
        
        //商品下单组
        $goodsDetailXml = '';
        foreach ($params['orderGoods'] as $key => $item ) 
        {
            //卖价
            $price              = $item['price'];
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity ;
            //单个商品价格
            $singleGoodsPrice   = bcdiv((string)$price, (string)$spec_num,2);
            //商品组
            $goodsDetailXml .= $this->arrToXml([
                'Detail'    => $this->arrToXml([
                    'ItemNumber'    => $item['supplier_skucode'],
                    'InnerPKG'      => $buyAcount,
                    'InnerUnit'     => 'PCS',
                    'UnitPrice'     => $singleGoodsPrice,
                    'UnitCurrency'  => 'RMB',
                ])
            ]);
        }

        $ShipToParty= [
            'Name'         => $orderInfo['buyer_realname'],
            'Name2'        => $orderInfo['receive_address'],
            'CityName'     => $orderInfo['city'],
            'State'        => $orderInfo['province'],
            'CountryCode'  => "CN",
            'Region'       => $orderInfo['district'],
            'TelNumber'    => $orderInfo['recveive_phone'],
            'ID'           => $orderInfo['buyer_idcard'],
            'IDType'       => "I",
        ];
        $data = [
            'EstPickUpDate'       => date("Y-m-d H:i:s",time()),
            'TransactionType'     => "NEW",
            'Customer'            => "ALL",
            'Warehouse'           => "HC001",
            'PreStockOutNo'       => $orderInfo['supplier_dsn'],
            'ShipToParty'         => $this->arrToXml($ShipToParty),
        ];
        
        $headerXml = $this->arrToXml(['Header'=>$this->arrToXml($data)]);
        $PreStockXml = $this->arrToXml(['PreStockOut'=>$headerXml.$goodsDetailXml]);
        $PreStockOutsXml = $this->arrToXml(['PreStockOuts'=>$PreStockXml]);
        $authXml = $this->arrToXml(
            ['Auth'=>$this->arrToXml([
            "user_code"  =>$this->config["user_code"],
            "password"  =>$this->config["password"],
            ])
                
            ]);
        
        $requestXml = $this->arrToXml([
            'Request'   => $authXml.$PreStockOutsXml
        ]);

        $requestParam = [
            'method'    => 'createOrder',
            'data'      => $data,
            'xmlData'   => $requestXml,
        ];
        $res = $this->execute($requestParam);
        if( $res['code'] == Normal::SUC ) {
            return Normal::returnCode(Normal::SUC,"订单推送成功",[
                'thirdpart_order_sn' => $res["data"]["ResponseID"]
            ]);
        }
        return $res;
    }
   
    /**
     * 获取取消订单
     */
    public function cancelOrder( $params = [] ) 
    {
        ini_set('serialize_precision', 16);
        if( empty($params['supplierOrder'])) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder ");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        
        //商品下单组
        $goodsDetailXml = $this->arrToXml(['Detail'=>""]);
        $data = [
            'TransactionType'     => "DELETE",
            'Customer'            => "ALL",
            'Warehouse'           => "HC001",
            'PreStockOutNo'       => $orderInfo['supplier_dsn'],
        ];
        $headerXml = $this->arrToXml(['Header'=>$this->arrToXml($data)]);
        $PreStockXml = $this->arrToXml(['PreStockOut'=>$headerXml.$goodsDetailXml]);
        $PreStockOutsXml = $this->arrToXml(['PreStockOuts'=>$PreStockXml]);
        $authXml = $this->arrToXml(
            ['Auth'=>$this->arrToXml([
                "user_code"  =>$this->config["user_code"],
                "password"  =>$this->config["password"],
            ])
            ]);
        $requestXml = $this->arrToXml([
            'Request'   => $authXml.$PreStockOutsXml
        ]);
        $requestParam = [
            'method'    => 'orderCancel',
            'data'      => $data,
            'xmlData'   => $requestXml,
        ];

        return $this->execute($requestParam);
    }
    
    /**
     * 根据SkuCode获取商品库存
     */
    public function queryGoodsListBySkuNo($param=[])
    {
        return $this->queryGoodsDetail($param['skuNos']);
    }
    
    /**
     * 查询商品详情
     */
    public function queryGoodsDetail($skuNos)
    {
        $details=[];
        $count=count($skuNos);
        $wg = new WaitGroup();
        $wg->add($count);
       
        foreach ($skuNos as $sku){
            co(function () use ($wg,$sku,& $details) {
                
                $data =['sku'=>$sku];
                $requestDataXml = $this->arrToXml(['RequestDate'=>date("Y-m-d H:i:s"."+08:00",time())]);
                $authXml = $this->arrToXml(
                    ['Auth'=>$this->arrToXml([
                        "user_code"  =>$this->config["user_code"],
                        "password"  =>$this->config["password"],
                    ])
                ]);

                $groupingLevelXml = $this->arrToXml(
                    ['GroupingLevel'=>$this->arrToXml([
                        'Type'          => "Lot",
                        'BalanceDate'   =>date("Y-m-d H:i:s"."+08:00",time())
                    ])
                ]);
                
                $searchingCriteriaXml = $this->arrToXml(
                    ['SearchingCriteria'=>$this->arrToXml([
                        'Criteria1'   => "ItemNumber",
                        'Value1'      =>$sku
                    ])
                ]);
                
                $requestXml = $this->arrToXml([
                    'Request'   => $authXml.$requestDataXml.$groupingLevelXml.$searchingCriteriaXml
                ]);
                $requestParam = [
                    'method'    => 'queryGoodsDetail',
                    'data'      => $data,
                    'xmlData'   => $requestXml,
                ];
                
                $responseParam = $this->execute($requestParam);
                if ($responseParam['code']==Normal::SUC && isset($responseParam['data']['Inventory'])){
                    $details[]=$responseParam['data'];
                }
                $wg->done();
            });
        }
        $wg->wait();
        return $details;
    
    }
    
    /**
     * 组装xml
     */
    public function arrToXml(  $params = [] )
    {
        $xml = '';
        foreach ($params as $key=>$val){
            $xml .= "<{$key}>{$val}</{$key}>";
        }
        return $xml;
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )  
    {
        if( empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        
        $method = $param['method'];
        $url = $this->RouteMap[$method] ."&user_code={$this->config['user_code']}";
        $parameter = [
            [
                'tag'       => $this->account.'_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $param['xmlData'],
                'method'    => 'post',
                'format'    => 'xml',
                'header'    => [
                    "Content-Type: application/xml"
                ],
        
            ],
        ];
        
        if( in_array($method,['queryGoodsDetail']) ) {
            $resTask = TaskWorker::instance()->addTask($parameter,'handleDiableTask');
        } else {
            $resTask = TaskWorker::instance()->addTask($parameter);
        }
        $resTask = current($resTask);
        $res     = $resTask['response']['result']; 

        
        $xmlObj  = simplexml_load_string($res,"SimpleXMLElement", LIBXML_NOCDATA);
        $jsonStr = json_encode($xmlObj);
        $resHttp = json_decode($jsonStr, true);
        if( isset($resHttp['ResponseStatus']) && $resHttp['ResponseStatus'] == "SUCCESS" ) {
            return Normal::returnCode(Normal::SUC,"操作成功",$resHttp);
        }
        
        $message = isset($resHttp['ResponseMessage']) ? $resHttp['ResponseMessage'] : '请求失败';
        return Normal::returnCode(Normal::FAIL,$message);
    }
}